import {getStorage} from '@/utils/localstoreage'
import Taro from '@tarojs/taro'

/**
 * @desc 从字符串中提取所有数字,包含正负整数，或正负小数
 * @param {val:string} 目标字符串
 * @param {digit:number} 保留小数位
 * */
export function splitNumByStr(val: string, digit: number) {
  // 清空 开头结尾空格 回车 tab
  let str = val.trim().replace(/\t\r/g, '')
  let reg = `[\\-\\+]?\\d+(\\.+\\d${digit ? '{0,' + digit + '}' : '+'}|\\d*)`
  let match = str.match(new RegExp(reg, 'g'))
  return match
    ? match.map(item => (digit ? Number(item) : Number(item).toFixed(0)))
    : null
}

/**
 * @desc 合并Class
 * @param {base:Function} 目标Class
 * @param {mixins:Fcuntion[]} 需要合并的Class数组
 * */
export const mixinClass = (base: any, ...mixins: any[]) => {
  const mixinProps = (target: any, source: any) => {
    Object.getOwnPropertyNames(source).forEach(prop => {
      if (/^constructor$/.test(prop)) {
        return
      }
      let descriptor = Object.getOwnPropertyDescriptor(source, prop)
      if (descriptor) Object.defineProperty(target, prop, descriptor)
    })
  }

  let Ctor
  if (base && typeof base === 'function') {
    Ctor = class extends base {
      constructor(...props: any) {
        super(...props)
      }
    }
    mixins.forEach(source => {
      mixinProps(Ctor.prototype, source.prototype)
    })
  } else {
    Ctor = class {}
  }
  return Ctor
}

/**检测数据类型 */
export function checkDataType(val: any) {
  if (Array.isArray(val)) {
    return 'array'
  } else if (val instanceof Object) {
    return 'object'
  } else if (typeof val === 'string') {
    return 'string'
  } else if (typeof val === 'number') {
    return 'number'
  } else if (val === null) {
    return null
  } else if (val === undefined) {
    return undefined
  } else {
    return val
  }
}

/**复杂数据递归查询所有属性 */
export function checkComplexDataw(data: any, cb?: Function) {
  if (typeof data === 'string') return
  // 控制跳出闭包
  let flag = true

  // 对应属性所属对象/数组的key值列表/下标列表
  let keyList: any[] = []

  loop(data)

  function loop(loopData: any) {
    if (!flag) return
    if (checkDataType(loopData) === 'array') {
      let copyData = loopData.flat(Infinity)
      let currentIdx = keyList.length
      for (let i = 0; i < copyData.length; i++) {
        if (keyList.length > currentIdx) {
          keyList = keyList.slice(0, currentIdx)
          keyList[currentIdx] = i
        } else {
          keyList.push(i)
        }
        loop(copyData[i])
      }
      keyList.splice(keyList.length - 1, 1)
    } else if (checkDataType(loopData) === 'object') {
      for (const key in loopData) {
        keyList.push(key)
        loop(loopData[key])
      }
      keyList.splice(keyList.length - 1, 1)
    } else {
      if (cb && typeof cb === 'function') {
        let returnData = cb(loopData, keyList)
        keyList.splice(keyList.length - 1, 1)
        flag = returnData === false ? false : true
      }
    }
  }
}

/**简单数据数据非空校验，或者复杂数据内是否包含null或者undefined */
export function checkEmpty(data: any) {
  let flag = false
  checkComplexDataw(data, (loopData: any) => {
    if (loopData === null || loopData === undefined) {
      flag = true
      return false
    }
  })
  return flag
}

/**树形结构数据递归查询所有子项 */
export function treeMap(target: any, childrenKey: any, cb?: Function): any {
  if (Array.isArray(target)) {
    for (let i = 0; i < target.length; i++) {
      const data = target[i]
      if (typeof cb === 'function') {
        let bol = cb(data)
        if (bol) return true
      }
      // treeMap继续检查当前项
      let bol = treeMap(data, childrenKey, cb)
      if (bol) return true
    }
  } else if (target instanceof Object) {
    // 存在子项时
    if (Array.isArray(target[childrenKey]) && target[childrenKey].length) {
      let bol = treeMap(target[childrenKey], childrenKey, cb)
      if (bol) return true
    }
  }
}

/**去除多余空格,回车,制表符(tab)等 */
export function removeStrInvaildSymb(data: string) {
  return checkDataType(data) === 'string'
    ? data.trim().replace(/\s|\n|\t/g, '')
    : data
}

/**判断是否是URL字符串 */
export function IsURL(str_url: string): Boolean {
  var v = new RegExp(
    '^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$',
    'i'
  )
  return v.test(str_url)
}

/**下拉选择输入关键字筛选 */
export const filterOption = (input: string, option: any, target?: string) => {
  return (
    option[target || 'label'].toLowerCase().indexOf(input.toLowerCase()) >= 0
  )
}

/**判断元素滚动到父元素底部 */
export const domIsScrollBottom = (parentId: string): Boolean => {
  let scrollHeight = document.getElementById(parentId)?.scrollHeight as number
  let offsetHeight = document.getElementById(parentId)?.offsetHeight as number
  let scrollTop = document.getElementById(parentId)?.scrollTop as number
  let diffHeight = scrollHeight - (offsetHeight + scrollTop)
  if (diffHeight <= 10) {
    return true
  } else {
    return false
  }
}
/**
 * @desc 获取某月内总天数
 * @param month : 可不传 月份，不传默认为当前月份
 * @param year  : 可不传 年份，不传默认为当前年份
 * @returns 当月总天数
 */
export const getCountDateByCurrentMonth = (
  month?: number,
  year?: number
): number => {
  var date = new Date()
  if (year === undefined) year = date.getFullYear()
  if (month === undefined) month = date.getMonth() + 1
  var day = new Date(year, month, 0)
  return day.getDate()
}

export const Log = (title: string, content: any, color?: string) => {
  console.log(`%c${title}`, `color:${color || 'orange'}`, content)
}

/**
 *
 * @param status 服务器返回的设备标识
 * @returns 对应到服务器中的图片路径
 */
export const matchDevStatusImgPath = (status: DeviceStatus): string => {
  return ''
}

/**
 *
 * @param scan :扫描后返回的二维码携带的url
 * @returns 返回url上携带的参数
 */
export function getParamByScan(scan: string): {[key: string]: any} | false {
  let reg = /^https:\/\/d.lohand.com:10001\/weixin\/miniprogram\?/
  let paramReg = /([^?&=]+)=([^?&=]+)/g
  let param: {[key: string]: any} = {}
  if (reg.test(scan)) {
    scan.replace(paramReg, function () {
      param[arguments[1]] = arguments[2]
      return ''
    })

    if (Object.keys(param).length <= 0 || param.devGId === undefined) {
      Taro.showToast({
        title: '二维码不包含有效数据!',
        icon: 'none'
      })
      return false
    }
    return param
  } else {
    Taro.showToast({
      title: '无效二维码!',
      icon: 'none'
    })
    return false
  }
}

/**
 *
 * @param status 设备状态
 * @returns 根据设备状态转为颜色
 */
export function devStatus2Color(status?: string): string {
  switch (status) {
    case '离线':
      return '#a4a4a4'
    case '异常':
      return '#F86A6B'
    case '适宜':
    case '在线':
    default:
      return '#1DC79C'
  }
}

/**
 *
 * @param status 参数状态
 * @returns 根据参数状态返回颜色
 */
export const paramStatus2Color = (status: string | undefined): string => {
  switch (status) {
    case '适宜':
      return '#22C49B'
    case '偏高':
      return '#F86A6B'
    case '偏低':
      return '#FFD314'
    case '故障':
    default:
      return '#A4A4A4'
  }
}

export function setNavTitle(val: string) {
  Taro.setNavigationBarTitle({
    title: val
  })
}

/**对象转url参数的键值对形式 */
export const qsStringify = (data: Object) =>
  Object.keys(data)
    .map(key => `${key}=${data[key] || ''}`)
    .join('&')

export const isLogin = () => {
  const userId = getStorage('userId')
  return userId ? true : false
}

/**
 *
 * @param  data 省市区
 * @returns 返回组合后的省市区
 */
export function addressJoin({
  province,
  city,
  district
}: {
  province: string
  city: string
  district: string
}) {
  if (province && district && city) {
    return `${province}-${district}-${city}`
  } else if (province && district) {
    return `${province}-${district}`
  } else if (province) {
    return `${province}`
  } else {
    return undefined
  }
}
